package org.brisling.service.sysman;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import org.brisling.domain.common.SysmanDomain;
import org.brisling.domain.sysman.inf.BizBeanDataModeler;
import org.brisling.domain.sysman.inf.ManageBeanDataModeler;
import org.brisling.domain.sysman.manage.UserRoleDomain;
import org.brisling.domain.sysman.relation.UserRoleRelationDomain;
import org.brisling.repository.inf.ManageRepository;
import org.brisling.repository.sysman.manage.inf.UserRoleRepo;
import org.brisling.repository.sysman.relation.inf.UserRoleRelationRepo;
import org.brisling.service.common.BaseManageService;
import org.brisling.util.LongUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/sysman")
/**
 * 
 * 系统维护中管理对象和授权对象的后台service类，提供关联对象和授权对象多对多关系的维护功能
 * @author : jackson wang
 * @Date   : 2015年6月8日 下午8:38:19
 * @version: 1.0
 */
public class MAndRService extends BaseManageService{
	
	@SuppressWarnings("rawtypes")
	private ManageRepository _reop = null;
	
	@SuppressWarnings("rawtypes")
	private  ManageBeanDataModeler _domain = null;
	
	
	
	@Autowired
	private UserRoleRepo urrepo;
	@Autowired
	private UserRoleRelationRepo urrrepo;
	
	
	
	@RequestMapping("/get/all")
	@ResponseBody
	/**
	 * 根据系统维护中主导对象唯一编码查找所有实体记录集合，并封装到<code>SysmanDomain</code>对象中，降低前后端通讯频率
	 * @param tid
	 * @return SysmanDomain 系统维护管理对象实体集合
	 * @see SysmanDomain
	 */
	public SysmanDomain getAll(@RequestParam(value="biztid",required=false) String tid){
		
		Long _tid = LongUtil.getLongValue(tid, null);
		
		SysmanDomain _domain = new SysmanDomain();
		if(_tid!=null){
			
			//m user role
			_domain.setManagedRole(super.getListByBiztid(tid, urrepo));
			
			_domain.setRelationRole(super.getListByBiztid(tid, urrrepo));
			
			
		}
			
		return _domain;
		
	}
	
	
	
	@SuppressWarnings("rawtypes")
	@RequestMapping("/{manageOrRelation}/get/{relevance}")
	@ResponseBody
	/**
	 * 根据系统维护中主导对象唯一编码查找所有实体记录集合
	 * @param tid 主导对象编码
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param body 前端传递的json数据参数
	 * @return List 系统维护管理对象实体集合
	 */
	public List<? extends ManageBeanDataModeler> getListByBiztid(@RequestParam(value="biztid",required=false) String tid,
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){		
		
		List<? extends ManageBeanDataModeler> _list =null;
		if(checkPathVariable(_type,_relevance))
			_list= super.getListByBiztid(tid, _reop);		
		
		return _list;
	}
	
	
	@RequestMapping("/{manageOrRelation}/getbize/{relevance}")
	@ResponseBody
	/**
	 * 根据系统维护中主导对象唯一编码查找关联对象实体记录集合
	 * @param tid 主导对象编码
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param body 前端传递的json数据参数
	 * @return List 关联对象实体集合
	 */
	public List<? extends BizBeanDataModeler> getBizeListByBiztid(@RequestParam(value="biztid",required=false) String tid,
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){		
		
		Long pid = LongUtil.getLongValue(tid, null);
		if(pid!=null)
			return this.getBizeListByBiztid(pid, _type, _relevance, body);
		else
			return null;
	}
	
	@SuppressWarnings("rawtypes")	
	/**
	 * 根据系统维护中主导对象唯一编码查找关联对象实体记录集合
	 * @param tid 主导对象编码
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param body 前端传递的json数据参数
	 * @return List 关联对象实体集合
	 */
	public List<? extends BizBeanDataModeler> getBizeListByBiztid(@RequestParam(value="biztid",required=false) Long tid,
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){		
		
		List<BizBeanDataModeler> retlist =new ArrayList<BizBeanDataModeler>();
		List<? extends ManageBeanDataModeler> _list =null;
		if(checkPathVariable(_type,_relevance)){
			_list= super.getListByBiztid(tid, _reop);	
			if(_list!=null&&_list.size()>0){
				for(ManageBeanDataModeler m:_list){
					retlist.add((BizBeanDataModeler)m.getBize() );
				}
			}
		}
		return retlist;
	}
	
	@SuppressWarnings("rawtypes")
	/**
	 * 
	 * 根据系统维护中主导对象唯一编码查找所有实体记录集合
	 * @param tid 主导对象编码
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @return List 系统维护管理对象实体集合
	 */
	public List<? extends ManageBeanDataModeler> getListByBiztid(Long tid,String _type,String _relevance){		
		
		List<? extends ManageBeanDataModeler> _list =null;
		if(checkPathVariable(_type,_relevance))
			_list= super.getListByBiztid(tid, _reop);		
		
		return _list;
	}
	
	@SuppressWarnings("rawtypes")
	@RequestMapping("/{manageOrRelation}/save/{relevance}")
	@ResponseBody
	/**
	 * 保存系统维护多对多关系实体	 
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param body 前端传递的json数据参数
	 * @return ManageBeanDataModeler 多对多关系实体
	 */
	public <S extends ManageBeanDataModeler> S save(			
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){
		
		S _mDomain = null;
		if(checkPathVariable(_type,_relevance)){
			S dept = super.bodyToObj(body, _domain.getClass());
			
			_mDomain = super.save(_reop, dept);
		}
		
		return _mDomain;
	}
	
	@RequestMapping("/{manageOrRelation}/del/{relevance}")
	@ResponseBody
	/**
	 * 删除系统维护中多对多关系实体
	 * @param tid 多对多关系实体唯一编码
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param body 前端传递的json数据参数
	 * @return String 返回操作状态码
	 */
	public String  del(
			@RequestParam(value="biztid",required=false) String tid,
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){
		
		
		if(checkPathVariable(_type,_relevance)){
			Long _tid = LongUtil.getLongValue(tid, null);
			
			return this.del(_reop, _tid);
		}
		
		return null;
	}
	
	/*
	 * 删除主导对象所有关联实体，用于删除及更新前操作
	 */
	@RequestMapping("/{manageOrRelation}/delAll/{relevance}")
	@ResponseBody
	/**
	 * 
	 * 删除系统维护中多对多关系实体集合
	 * @param tid 多对多关系实体唯一编码集合
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param body 前端传递的json数据参数
	 * @return String 返回操作状态码
	 */
	public String  delAll(
			@RequestParam(value="biztid",required=false) String tid,
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){		
		
			Long _tid = LongUtil.getLongValue(tid, null);
			
			return this.delAll(_type,_relevance,_tid);			
	}
	
	@SuppressWarnings("rawtypes")
	/**
	 * 根据系统维护中主导对象唯一编码集合删除多对多关系实体
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @param tid 主导对象唯一编码集合
	 * @return 操作状态码
	 */
	public String  delAll(String _type,String _relevance,Long tid){
		
		
		if(checkPathVariable(_type,_relevance)){
			List<? extends ManageBeanDataModeler> _list = this.getListByBiztid(tid, _reop);
			if(_list!=null)
			    return super.delAll(_reop, _list);
		}
		
		return null;
	}
	
	@SuppressWarnings("rawtypes")
	/**
	 * 
	 * 删除系统维护中多对多关系实体集合
	 * @param _list 多对多关系实体集合
	 * @param _type 业务分类
	 * @param _relevance	关联类型(manage or relation)
	 * @return String 操作状态码
	 */
	public String  delAll(String _type,String _relevance,List<? extends ManageBeanDataModeler> _list){
		
		
		if(checkPathVariable(_type,_relevance)){
			if(_list!=null)
			    return super.delAll(_reop, _list);
		}
		
		return null;
	}
	
	/*
	 * 删除主导对象所有关联实体，用于删除及更新前操作
	 */
	@RequestMapping("/{manageOrRelation}/delByBiztid/{relevance}")
	@ResponseBody
	/**
	 * 
	 * 根据多对多关系主导对象实体的主导对象编码，删除多对多关系实体
	 * @param _type 业务分类
	 * @param _relevance 关联方式(manage or relation)
	 * @param tid 多对多关系主导对象实体唯一编码
	 * @param body 前端传递的json数据对象
	 * @return 操作状态码
	 */
	public String  delByBiztid(
			@RequestParam(value="biztid",required=false) String tid,
			@PathVariable("manageOrRelation") String _type,
			@PathVariable("relevance") String _relevance,
			@RequestBody String body){		
		
			Long _tid = LongUtil.getLongValue(tid, null);
			
			return this.delByBiztid(_type,_relevance,_tid);
		
		
		
	}
	
	/**
	 * 根据多对多关系主导对象实体的主导对象编码，删除多对多关系实体
	 * @param _type 业务分类
	 * @param _relevance 关联方式(manage or relation)
	 * @param tid 多对多关系主导对象实体唯一编码
	 * @return 操作状态码
	 */
	public String  delByBiztid(String _type,String _relevance,Long tid){			

		if(checkPathVariable(_type,_relevance)){
			return super.delByBiztid(_reop, tid);
		}			
		return null;		
	}
	
	
	
	/**
	 * 删除系统维护中多对多关系实体
	 * @param tid 多对多关系实体唯一编码
	 * @param _type 业务分类
	 * @param _relevance 关联方式(manage or relation)
	 * @return 操作状态码
	 */
	public String  del(Long tid,String _type,	String _relevance){
		
		
		if(checkPathVariable(_type,_relevance)){			
			
			 super.del(_reop, tid);
			 return "200";
		}
		
		return null;
	}
	
	
	
	
	@SuppressWarnings({ "rawtypes" })
	/**
	 * 保存系统维护中多对多关系对象实体
	 * @param _type 业务分类
	 * @param _relevance 关联方式(manage or relation)
	 * @param list 待保存的多对多关系实体集合
	 * @return 返回保存后的实体对象集合
	 */
	public List<? extends ManageBeanDataModeler> save(
			String _type,
			String _relevance,
			List<? extends ManageBeanDataModeler> list
			){
		
		List<? extends ManageBeanDataModeler> _mDomain = null;
		if(checkPathVariable(_type,_relevance)){			
			_mDomain =  super.save(_reop, list);
		}
		
		return _mDomain;
	}
	
	/**
	 * 根据业务分类与关联方式确认业务实体对象类型与业务仓库对象
	 * @param _type 业务分类
	 * @param _relevance	关联方式(manage or relation)
	 * @return 是否成功匹配标志，成功匹配，返回<code>True</code>,匹配失败,返回<code>False</code>
	 */
	private Boolean checkPathVariable(String _type,String _relevance){
		Boolean _mached = false;
		if(_type!=null){
			switch(_type){
				case "manage":
					if(_relevance!=null){
						switch(_relevance){
							
							case "userRole":
								_reop = urrepo;
								_domain = new UserRoleDomain();
								_mached = true;
								break;
							
						}
					}
					
					break;
				case "relation":
					if(_relevance!=null){
						switch(_relevance){
							
							case "userRole":
								_reop = urrrepo;
								_domain = new UserRoleRelationDomain();
								_mached = true;
								break;
							
						}
					}
					
			}
		}
		return _mached;
	}
	
	/**
	 * 根据ManageBeanDataModeler的biztid和bizeid值，形成string类型组合键(以数值类型id值合并而成，避免因数值类型出现数据偏差)
	 * 以_ug_new 为基准map，剔除_ug_old中已有的数据，
	 * @param _ug_new	变更配置情况
	 * @param _ug_old	匹配配置情况
	 * @return 经过数据过滤后的多对多关系实体对象集合
	 */
	@SuppressWarnings({ "rawtypes" })
	public List<? extends ManageBeanDataModeler> filerExistData(
			List<? extends ManageBeanDataModeler> _ug_new,
			List<? extends ManageBeanDataModeler> _ug_old){
		List<ManageBeanDataModeler> retList = null ;
		
		//判断数据库中是否为空
		if(_ug_old!=null&&_ug_old.size()>0){
			
			//判断新增数据是否为空
			if(_ug_new!=null&&_ug_new.size()>0){
				LinkedHashMap<String,ManageBeanDataModeler> _map = new LinkedHashMap<String,ManageBeanDataModeler>();
				//新数据入栈
				for(ManageBeanDataModeler m:_ug_new){					
					String _tmpKey = ""+m.getBiztid()+m.getBizeid();
					_map.put(_tmpKey, m);
				}
				
				//剔除已有数据				
				for(ManageBeanDataModeler om:_ug_old){
					String _tmpKey = ""+om.getBiztid()+om.getBizeid();
					if(_map.containsKey(_tmpKey))
						_map.remove(_tmpKey);
				}
				
				if(!_map.isEmpty()){
					retList = new ArrayList<ManageBeanDataModeler>();
					
					for(Entry<String, ManageBeanDataModeler> en:_map.entrySet()){
						retList.add(en.getValue());
					}
				}
			}
			
		}else{
			//数据库中无数据，直接返回新数据
			return _ug_new;
		}
		
		return retList;
	}
	
	/**
	 * 同步配置变更情况
	 * @param clazz			关联实体对象
	 * @param bizt			关联实体对象主导类
	 * @param _bizeList		关联实体对象关联对象集合
	 * @param _type			关联实体对象配置模式(manage or relation)
	 * @param _relevence	关联实体对象定义(usergroup,userpermission,userrole)
	 */
	@SuppressWarnings({ "rawtypes", "unused" })
	private void persistMAndR(Class<? extends ManageBeanDataModeler> clazz,
								BizBeanDataModeler bizt,
								List<? extends BizBeanDataModeler> _bizeList,
								String _type,
								String _relevence){
		List<? extends ManageBeanDataModeler> ug_new = getCombinedDomain(clazz,bizt,_bizeList);
		
		List<? extends ManageBeanDataModeler> ug_old = this.getListByBiztid(bizt.getId(), _type,_relevence);
		
		List<? extends ManageBeanDataModeler> _filterList = this.filerExistData(ug_new, ug_old);
		if(_filterList!=null&&_filterList.size()>0){
			
			this.save(_type,_relevence, _filterList);
			
		}
		
		List<? extends ManageBeanDataModeler> _delList = this.filerExistData( ug_old,ug_new);
		if(_delList!=null&&_delList.size()>0){
			
			this.delAll(_type,_relevence, _delList);
			
		}
	}
	
	/**
	 * 同步配置变更情况(保存新增的配置，删除已取消的配置)	 
	 * @param bizt			关联实体对象主导类
	 * @param ug_new		关联实体对象关联对象集合
	 * @param _type			业务分类
	 * @param _relevence	关联实体对象定义(usergroup,userpermission,userrole)
	 */
	@SuppressWarnings("rawtypes")
	public void persistMAndR(BizBeanDataModeler bizt,
								List<? extends ManageBeanDataModeler> ug_new,
								String _type,
								String _relevence){
		
		
		List<? extends ManageBeanDataModeler> ug_old = this.getListByBiztid(bizt.getId(), _type,_relevence);
		
		List<? extends ManageBeanDataModeler> _filterList = this.filerExistData(ug_new, ug_old);
		if(_filterList!=null&&_filterList.size()>0){
			
			this.save(_type,_relevence, _filterList);
			
		}
		
		List<? extends ManageBeanDataModeler> _delList = this.filerExistData( ug_old,ug_new);
		if(_delList!=null&&_delList.size()>0){
			
			this.delAll(_type,_relevence, _delList);
			
		}
	}
	
	/**
	 * 根据多对多关系主导对象实体，与多对多关系关联对象实体集合，拼装管理实体对象
	 * @param clazzMAndR	关联实体类
	 * @param bizt			关联实体主导对象
	 * @param _bizeList		关联实体关联对象集合
	 * @return List 多对多实体集合
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<? extends ManageBeanDataModeler> getCombinedDomain(
			Class<? extends ManageBeanDataModeler> clazzMAndR,
			BizBeanDataModeler bizt,List<? extends BizBeanDataModeler> _bizeList){
		
		List<ManageBeanDataModeler> mmList = new ArrayList<ManageBeanDataModeler>();			 
			 
		if(_bizeList!=null&&_bizeList.size()>0){
			for(BizBeanDataModeler bize:_bizeList){
				 ManageBeanDataModeler mrDomain = null;
					try {
						mrDomain = clazzMAndR.newInstance();
					} catch (InstantiationException | IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					 mrDomain.setBizt(bizt);
					 mrDomain.setBize(bize);
					 mmList.add(mrDomain);
			}			 
		 }
		
		return mmList;
	}
	
	/**
	 * 关联实体对象唯一编码集合查找所有关联实体对象集合，并与主导对象实体拼装管理实体对象
	 * @param clazzMAndR 关联实体对象
	 * @param bizt		 关联实体主导对象	
	 * @param clazze	关联实体关联对象类名称
	 * @param bizeList	关联实体对象主键集合
	 * @return List 拼装后的管理实体对象
	 */
	@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
	private List<ManageBeanDataModeler> getCombinedDomain(
			Class<? extends ManageBeanDataModeler> clazzMAndR,BizBeanDataModeler bizt,
			Class<? extends BizBeanDataModeler> clazze,List<Long> bizeList){
		List<ManageBeanDataModeler> mmList = new ArrayList<ManageBeanDataModeler>();
		
		if(bizeList!=null&&bizeList.size()>0){ 
			
				 for(Iterator<Long> ite=bizeList.iterator();ite.hasNext();){
					 ManageBeanDataModeler mrDomain = null;
					 BizBeanDataModeler bize = null;
					try {
						mrDomain = clazzMAndR.newInstance();
						bize = clazze.newInstance();
					} catch (InstantiationException | IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					 mrDomain.setBizt(bizt);
					 bize.setId(ite.next());
					 mrDomain.setBize(bize);
					 mmList.add(mrDomain);
				 }
			 
		}
		return mmList;
	}
}
